package com.auth.manage.gateway.auth;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.dev33.satoken.filter.SaFilterErrorStrategy;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.auth.manage.common.user.api.constant.UserPermission;
import com.auth.manage.common.user.api.constant.UserRole;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Slf4j
@Configuration
public class SaTokenConfig {
    @Bean
    StpInterfaceImpl stpInterface() {
        return new StpInterfaceImpl();
    }

    @Bean
    public SaReactorFilter getSaReactorFilter() {
        return new SaReactorFilter()
                // 拦截地址
                .addInclude("/**")    /* 拦截全部path */
                // 开放浏览器的图标
                .addExclude("/favicon.ico")
                // 鉴权方法：每次访问进入
                .setAuth(obj -> {
                    // 登录校验 -- 拦截所有路由，并排除/user/doLogin 用于开放登录
                    // StpUtil.checkLogin()：检查是否携带Cookie / 请求头，校验是否有效、是否绑定了loginId
                    SaRouter.match("/**", "/user/login", r -> StpUtil.checkLogin());

                    // 先实名认证，通过后再判断是否冻结
                    SaRouter.match("/user/**", r -> StpUtil.checkPermissionOr(UserPermission.AUTH.name()));
//                    SaRouter.match("/user/**", r -> StpUtil.checkPermission(UserPermission.FROZEN.name()));
                })
                // 异常处理方法：每次setAuth函数出现异常时进入，抛出的异常是SaToken内部定义的异常
                .setError(this::getSaResult)
                ;
    }
    // 自己封装异常，让错误信息更详细
    private SaResult getSaResult(Throwable throwable){
        // 相当于Instance of:判断是否为那个类的实例，检查的是对象的实际类型,如果是会转为那个对象
        switch (throwable){
            case NotLoginException notLoginException:
                log.error("请先登录");
                return SaResult.error("请先登录");
            case NotRoleException notRoleException:
                if (UserRole.ADMIN.name().equals(notRoleException.getRole())){
                    log.error("当前用户不是管理员，无法操作");
                    return SaResult.error("当前用户不是管理员，无法操作");
                }
                log.error("没有该角色权限");
                return SaResult.error("没有该角色权限");
            case NotPermissionException notPermissionException:
                if (UserPermission.AUTH.name().equals(notPermissionException.getPermission())){
                    log.error("请先实名认证");
                    return SaResult.error("请先实名认证");
                }
                log.error("无权操作");
                return SaResult.error("无权操作");
            default:
                throw new IllegalStateException("Unexpected value: " + throwable);
        }
    }
}
